perm filename PART2[DOC,BGB]1 blob sn#092015 filedate 1974-03-20 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00020 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	PART II
C00004 00003	1.0  A SIMPLE EXAMPLE.
C00008 00004	
C00010 00005	
C00013 00006	MEMORY - TOP LEVEL GEM STRUCTURE.
C00018 00007	
C00028 00008	FRAME ← APTRAN(ENTITY,FRAME)
C00031 00009	 2.0  LINK AND DATUM ACCESSING.
C00035 00010	 3.0  WINGED EDGE PRIMITIVES.
C00037 00011	 4.0  EULER MAKE PRIMITIVES.
C00039 00012	 5.0  EULER KILL PRIMITIVES.
C00040 00013	 6.0  EASY POLYHEDRON ROUTINES.
C00041 00014	 7.0  EUCLIDEAN TRANSFORMATIONS.
C00044 00015	 8.0  GEOMETRIC MEASURE ROUTINES.
C00045 00016	 9.0  BODY INTERSECTION AND CUTTING.
C00046 00017	10.0  IMAGE FORMATION ROUTINES.
C00047 00018	11.0  INPUT/OUTPUT ROUTINES.
C00048 00019	12.0  AUXILLARY ROUTINES: III DISPLAY AND ARITHMETIC.
C00049 00020	PART III
C00052 ENDMK
C⊗;
PART II

PART II - GEOMED AS A SAIL OR LISP ACCESSIBLE GRAPHICS COMMAND LANGUAGE.

	1.0	A SIMPLE EXAMPLE.
	2.0	LINK AND DATUM ACCESSING.
	3.0	WINGED EDGE PRIMITIVES.
	4.0	EULER MAKE PRIMITIVES.
	5.0	EULER KILL PRIMITIVES.
	6.0	EASY POLYHEDRON ROUTINES.
	7.0	EUCLIDEAN TRANSFORMATIONS.
	8.0	GEOMETRIC MEASURE ROUTINES.
	9.0	BODY INTERSECTION AND CUTTING.
       10.0	IMAGE FORMATION ROUTINES.
       11.0	INPUT/OUTPUT ROUTINES.
       12.0	AUXILLARY ROUTINES: III DISPLAY AND ARITHMETIC.

1.0  A SIMPLE EXAMPLE.

	This  first explaination  presents  a  subset of  GEOMES  for
construction  and animation  using  bricks. The  following discussion
refers to the sample program, TEST1.SAI  shown on the next page.   In
the  example,   GEOMES  is  declared  by  requiring the  source  file
GEOMES.HDR[GEM,HE];  GEM stands for Geometric Modeling; HE stands for
Hand/Eye.   When executed,  TEST1 displays one  cubic brick  tumbling
around another.

	In GEOMES worlds,  windows, camera, bodies, faces,  edges and
vertices  are referred to  by integer pointers.  A world is  a set of
bodies; a camera is  a camera model; a  window ties pairs of  cameras
and worlds together;  and a body is a model  of a polyhedron composed
of faces,  edges and vertices. For this introduction, all bodies will
be rectangular right  prisms. To get the data structure  initialized,
write the following instruction:

	GEONIT;
	BODY ← MKCUBE(XSIDE,YSIDE,ZSIDE);	make cubic solid.
	BODY ← MKCOPY(BODY);			make a copy.
	
	The  routine  MKCUBE generates a rectangular right prism with
sides of length XSIDE, YSIDE and ZSIDE. The center of  the  prism  is
initially  at  the  world  origin,  (0,0,0).   The arguments are real
numbers representing feet. The initial camera is located sixteen feet
above  the X-Y plane and is looking down with a 12.5 millimeter lens,
which means that any block with sides less than 20 feet  will  be  in
view.  The routine MKCOPY will return a copy of its argument, the new
body will have the same location and orientation as the old one,  and
must be moved before doing a hidden line elimination.

	WHOLE ← BATT(PART,WHOLE);	body attach.
	PART  ← BDET(PART);		body detach.

	The BATT routine attachs one body to  another  so  that  when
something  is  moved  or copied all its parts will be moved or copied
too. Naturally, parts may have subparts and so on. A  body  is  freed
from its role as a part of something by the BDET routine.

BEGIN "TEST1"
	DEFINE α="COMMENT";
	DEFINE π="3.1415927";
	REQUIRE "GEOMES.HDR[GEM,HE]" SOURCE_FILE;
	INTEGER B1,B2,F,E,V,V0,T;
	INTEGER WORLD,WINDOW,CAMERA;

α UNIVERSE CREATION;

	GEONIT;
	
α BODY CREATION;
	
	B1 ← MKCUBE(4.0,1.0,2.0);      α MAKE RECTANGULAR PRISM;
	B2 ← MKCOPY(B1);	       α COPY THE PRISM;

α ACTION;

	FOR T←1 STEP 1 UNTIL 30 DO
		 OUTSTR(13&10);		α FLUSH THE PAGE PRINTER;
	TRANSLATE(B1,0,0,4);		α 4 FEET +Z TOWARDS CAMERA;
	ROTATE(B2,π/8,π/8,0);		α ROTATION ABOUT X & Y AXES;
	WHILE TRUE DO 
	BEGIN
		ROTATE(B1,0,-π/17,0);	α ROTATION CW ABOUT Y-AXIS;
	FOR T←1 STEP 1 UNTIL 40 DO
	BEGIN 
		ROTATE(B1,π/20,0,0);	α ROTATION CCW ABOUT X-AXIS;
		ROTATE(B2,0,π/16,0);	α ROTATION CCW ABOUT Y-AXIS;
		SHOW2(0,1);		α DISPLAY A SIMULATED IMAGE;
		IF INCHRS≥1 THEN DONE;	α EXIT ON TYPE-ANY-KEY;
	END;
	END;

END "TEST1"; BGB 19 MARCH 1973.

EUCLIDEAN TRANSFORMATIONS:

	TRANSLATE(OBJECT,DELTAX,DELTAY,DELTAZ);
	ROTATE(OBJECT,ABOUTX,ABOUTY,ABOUTZ);

	The   TRANSLATE  routine  takes  four  arguments,  the  first
argument is the integer pointing at the thing to be  translated,  the
next  three  arguments  are real numbers indicating a displacement in
feet parallel to the X, Y and Z world axes respectively.   The  world
frame of reference is right handed and orthogonal.

	The  ROTATE  routine takes four arguments, the first argument
is the integer pointing at the thing to  be  rotated,  and  the  next
three arguments are real numbers indicating a angular displacement in
radians about the X, Y and Z world axes  respectively.  The  positive
direction  of  rotation  is  counterclockwise; which is the so called
right hand rule convention.


IMAGE OPERATIONS:

	INTEGER PROCEDURE SHOW1 (INTEGER WINDOW,GLASS);
	INTEGER PROCEDURE SHOW2 (INTEGER WINDOW,GLASS);

	There are  two simple  display operations:  SHOW1 and  SHOW2.
The  SHOW1 routine displays  all the  edges appearing in  the window.
The SHOW2  routine performs a  hidden line  elimination and  displays
only the  portions of edges that  are not hidden. Both  routines take
two  arguments, the first argument is the  window to be displayed and
the second  argument is  the number,  0 to 15,  of the  III piece  of
glass to which  the display buffer is sent.  When the Window argument
is zero the "now" window is used.
MEMORY - TOP LEVEL GEM STRUCTURE.

	The top level  of the GEM  data structure is  constructed out
of  six kinds of  nodes: UNIVERSE,  WORLD, IMAGE, WINDOW,  CAMERA and
LAMP; by way  of contrast the polyhedron  data structure consists  of
BODY,  FACE, EDGE,  and VERTEX  nodes;  and the  auxillary nodes  are
classified  as EMPTY, FRAME, XNODE, YNODE  and ZNODE. Initially there
is no image  node and  only one Universe,  World, Window, Camera  and
Lamp Node. The approximate interconnections of the nodes is:

			  ←←  UNIVERSE  →→ 
			/	  ↓	    \
	 	      /	     empty nodes      \
		worlds				displays
		  ↓				  ↓
		  ↓   				windows
		  ↓				  ↓
 suns	←←←←	WORLD	 →→→→	cameras  ←←←←	WINDOW
  ↓		  ↓		  ↓		
 SUN		  ↓		CAMERA	
		  ↓	      /	       \
	 	  ↓	synthetic	perceived
		  ↓	 images		 images
		  ↓	    ↓		    ↓
		  ↓	    ↓		    ↓
		  ↓	    ↓		    ↓
		3D bodies	"2D" bodies
		    ↓                 ↓
		 faces, edges and vertices.


	Now for  the casual  definitions of  the SIX  top nodes.  The
Universe node is unique  and all nodes are connected to it so that it
serves as an OBLIST node. The GEM universe is the mental  universe or
universe of  discourse for geometric modeling.  Immediately below the
universe node  is a ring of world nodes and a ring or displays (and a
list of empty  nodes). A world node  is for representing one  physics
like  world at a  particular moment  in time;  three kinds  of worlds
might include a  perceived here-and-now  world or map;  a desired  or
goal world; and  a world of  prototype platonic forms,  or dictionary
world.  The  world points  immediately  at a  ring  of  light sources
(lamps), a ring of physical camera models, and a ring of bodies.

	Unless  otherwise  noted,   all  arguments  and   values  are
integers; subroutines  executed for effect return integer value zero.

GEOMED;

	Passes control  to the geometric  editor,  GEOMED;  which has
its own arcane  jump table command scanner, display modes, I/O and so
on; see the first half of this document for further details. When the
exit command  "εE" is given, GEOMED  returns the address of  the node
which is at the top of its stack (or zero).

GEODPY;		...refreshs the "now" display of GEOMED.

SHOW1(WINDOW,GLASS);

	Display all the edges of all the objects of  the world of the
given window (or  the "now" window if the window  argument is 0). The
GLASS is  an integer  between 0  and '17;  GLASS corresponds  to  the
system's pieces of glass; use GLASS set to 1  if you do not know what
a  piece of glass  is. The command  SHOW1(0,1) is the  fastest way to
display the "now" world.

SHOW2(WINDOW,GLASS);

	Display all the visible edges of all the objects of the world
of the given window (or the "now" window if the window argument is 0).
SHOW2 calls the hidden line eliminator OCCULT.

SHOW3(WINDOW,GLASS);

	Display all the faces that are towards the camera. SHOW3 is about
as fast as SHOW1, but with the back sides of everything being hidden.

FRAME ← APTRAN(ENTITY,FRAME);

	Apply a  Euclidean Transformation  to an  ENTITY; the  entity
may be a Body, Face, Edge, Vertex, Camera or Frame.

FRAME ← INTRAN(FRAME);
	
	Invert a  Euclidean Transformation; the invert of a Euclidean
Transformation will undo the given transformation.

REAL_DEL ← DISTAN(V1,V2);

	Given to vertices, return the distance between them.

NODE ← MKNODE(TYPE);

	Make (that is allocate)  a 12 word GEM node  with the integer
TYPE in it word 0.

KLNODE(NODE);

	Kill node (that is release) a 12 word GEM node.

WORLD ← MKWORLD;

	Make world,  adds  a new  world at  the end  of the  universe
node's  world  ring. The  first  world of  the  universe  is accessed
W1←PWRLD(UNIVERSE); the remaining  worlds are accessed  W2←PWRLD(W1);
W3←PWRLD(W2); until  the ring  points to the  first world  again. The
world ring is never empty.

CAMERA ← MKCAMERA(WORLD);

	Make a camera in a given world; if the world argument is zero
the default world is the "now" world.

NEW_WINDOW ← MKWINDOW(CAMERA,OLD_WINDOW);

	CAMERA  argument may  be  zero  (uses "now"  camera);  WINDOW
argument may be  zero to create a new display ring; otherwise the new
window is  placed into  the display  ring of  the  given window.  The
universe has a ring of displays;  only the "now" display is refreshed
by  the subroutine  GEODPY; a  display is  a ring  of windows;  and a
window merely points to a camera, which points at a world.
 2.0  LINK AND DATUM ACCESSING.

	The GEOMED data  structure  is  implemented  as  twelve  word
blocks  containing pointers and data in the fashion usual to graphics
and simulation; an introduction to this technology can  be  found  in
Knuth.    The  language of implementation is PDP-10 machine code, and
although the data and subroutines discussed below are accessible from
SAIL,  with  the  exception of CORGET, no SAIL routines are called by
GEOMES routines. In particular, GEOMES emphatically has nothing to do
with LEAP.

	The  twelve  word  blocks of GEOMES are called "nodes". Nodes
are referred to by their actual machine  address  in  the  user  core
image, which is an integer called a "link". Thus the subroutines that
take nodes as arguments or return nodes as values pass  links  rather
than  the  nodes  themselves.   In  SAIL,  the user core image can be
accessed as a special array named MEMORY. Using the MEMORY feature of
SAIL,  the  GEOMES.HDR  defines  names  for  where links and data are
stored relative to the origin of a node.
 3.0  WINGED EDGE PRIMITIVES.


  1-5 	MKB,MKF,MKE,MKV,MKFRAME.	Make BFEV Nodes.
 6,7,8 	WING,INVERT,EVERT		Make and change wing pointers.
   9.	LINKED				Find if two entities are linked.
 10,11 	ECW,ECCW,			Edge fetching around FV perimeter.
 12-16 	OTHER,VCW,VCCW,FCW,FCCW		Face-vertex fetching from an edge.
 17-19 	BDET,BATT,BGET			Body parts linking and body get.

INVERT(EDGE);

	An edge is a  directed vector with a positive  and a negative
vertex; INVERT flip the orientation of an edge vector and returns the
same edge.

EVERT(BODY);

	Evert turns  a  body inside  out,   or  vice  versa.   A  GEM
polyhedral  surface has  an  inside  and an  outside;  the inside  is
defined  by the orientation of the four  wing pointers in edge nodes;
the evert primitives changes the  order of these pointers in  all the
edges of the given body.

 4.0  EULER MAKE PRIMITIVES.

4.1 	BNEW ← MKBFV;   	Make vertex polyhedron.
4.2 	VNEW ← MKEV(F,V);	MAKES NEW EDGE AND VERTEX SUCH THAT:
				VNEW = NVT(ENEW); V = PVT(ENEW);
	VNEW ← ESPLIT(E);	MAKES NEW EDGE AND VERTEX...
4.3 	ENEW ← MKFE(V1,F,V2);   MAKES NEW FACE AND EDGE SUCH THAT:
				FNEW = NFACE(ENEW); F = PFACE(ENEW);
				  V1 = PVT(ENEW);  V2 = NVT(ENEW).
4.4	ENEW ← GLUEE(F1,V1,F2,V2);	MAKES NEW EDGE, KILLS F2,
				AND MAKES A HOLE OR KILLS A BODY.
				  V1 = PVT(ENEW);  V2 = NVT(ENEW).
---------------------------------------------------------------------
4.2	VNEW ← MKEV(FACE,VERTEX);
	VNEW ← ESPLIT(EDGE);

	Make a new  edge and a new vertex in  the given FACE from the
given VERTEX; the  new vertex is  return, VNEW; the  new edge can  be
accessed by taking PED(VNEW).
ESPLIT,	makes a new edge and a  new vertex, VNEW; the new edge may  be
obtained by taking PED(VNEW); the new  edge is place between VNEW and
PVT(EDGE).

4.3	ENEW ← MKFE(V1,FACE,V2);

	Make a new face and a new edge by  joining V1 and V2 of FACE.
The new  edge is returned, ENEW; the new  face may always be obtained
by taking NFACE(ENEW).
 5.0  EULER KILL PRIMITIVES.

5.1 	QNEW ← KLBFEV(Q);	Kill entity.
5.2 	   F ← KLFE(E);		Kill E and NFACE(E), return PFACE(E).
5.3 	   E ← KLEV(V);		Kill V and PED(V), return other E of V.
	   V ← KLEV(E);		Kill E and NVT(E), retirn PVT(E).
5.4 	FNEW ← UNGLUE(E);	Undo an GLUEE.
 6.0  EASY POLYHEDRON ROUTINES.

6.1	BODY ←	GLUE(FACE1,FACE2);	Glue face-face.
6.2	QNEW ←	MKCOPY(ENTITY);		Make copy.
6.3	FACE ←	SWEEP(FACE,FLAG);	Sweep cylinder.
6.4	FACE ←	ROTCOM(FACE);		Rotation completion.
6.5	PEAK ←	PYRAMID(FV);		Make pyramid on a face (or vertex).
6.6	BODY ←  FVDUAL(BODY);		Make face/vertex dual of a body.
6.7	BNEW ←  MKCUBE(DX,DY,DZ);	Make right rectangular prism.
6.8	BNEW ←  MKCYLN(RADIUS,N,DZ);	Make right cylinder.
6.9	BNEW ←  MKBALL(RADIUS,M,N);	Make sphere approximation.

 7.0  EUCLIDEAN TRANSFORMATIONS.

FRAME ← TRANSLATE(INTEGER ENTITY; REAL DELTAX,DELTAY,DELTAZ);
FRAME ←    ROTATE(INTEGER ENTITY; REAL ABOUTX,ABOUTY,ABOUTZ);
FRAME ←    SHRINK(INTEGER ENTITY; REAL SCALEX,SCALEY,SCALEZ);

	When  the  ENTITY argument  is  non-zero,  these  subroutines
perform   the   indicated   Euclidean  Transformation:   translation,
rotation, dilation and reflection. When the ENTITY argument  is ZERO,
then  a  FRAME  node   representing  the  desired  transformation  is
returned.

FRAMES and EUCLIDEAN TRANSFORMATIONS

	A frame  node  has two  intrepretations: it  may  be used  to
represent  a  frame of  reference  or it  may  be used  to  specify a
Euclidean transformation.

	As a frame of reference the XWC,  YWC, ZWC datums contain the
location  of the origin  of the frame  in world  coordinates; and the
remaining nine datums IX,IY,IZ, JX,JY,JZ, KX,KY,KZ are the components
of three  unit vectors  I, J,   and K that  determine a  right handed
rectangular  Cartesian coordinate system. The  nine components of the
unit vectors form an orthonormal rotation matrix.

	As a Euclidean transformation, the frame is applied to the
3-D world coordinates of an entity Q to make new coordinates.
---------------------------------------------------------------------
|  APTRAN's inner most subroutine.				    |
|  Expects arguments in V and Q. Clobbers 1,2,X,Y,Z.		    |
|								    |
|	X ← XWC(V);						    |
|	Y ← YWC(V);						    |
|	Z ← ZWC(V);					            |
|						 		    |
|	XWC(V) ← X*IX(Q) + Y*JX(Q) + Z*KX(Q) + XWC(Q);		    |
|	YWC(V) ← X*IY(Q) + Y*JY(Q) + Z*KZ(Q) + YWC(Q);		    |
|	ZWC(V) ← X*IZ(Q) + Y*JZ(Q) + Z*KZ(Q) + ZWC(Q);		    |
---------------------------------------------------------------------

HOMOGENEOUS COORDINATES

	The interpretation of frame nodes can be given in the
four by four notation of homogeneous coordinates.
 8.0  GEOMETRIC MEASURE ROUTINES.
 9.0  BODY INTERSECTION AND CUTTING.
10.0  IMAGE FORMATION ROUTINES.
11.0  INPUT/OUTPUT ROUTINES.
12.0  AUXILLARY ROUTINES: III DISPLAY AND ARITHMETIC.
PART III

SYSTEMS PROGRAMMING NOTES:

	The GEOMES source files  are all found on the disk area [GEM,HE];
the file  Z.CMD is an RPG command file  such that the monitor command
"COMPILE @Z.CMD" will compile everything.

MAKING A GEOMEL

.R ILISP 50
---------------------------------------------------------------------
DESCRIPTION OF GEOMED MACHINE CODE.

	The over all program structure of GEOMED is determined by the
urge  to have approximately one  subroutine per page  of source code.
The subroutine  calling  conventions are  SAIL like;  accumulator  17
(named  "P") is used  as  a  push down  list  for  arguments and  return
addresses; a calling sequence goes: PUSH P,ARG↔ PUSH P,ARG↔ ... PUSHJ
P,SUBR and  a subroutine  return must  fix  up the  stack SUB  P,[XWD
N+1,N+1] and JRST @N+1(P).
	
	The somewhat unusal  appearance of GEOMED machine code arises
from the  use  of  FAIL  assembler macros  to  implement  ALGOL  like
subroutine notation and KNUTH like datum/link  notation; and from the
use of "double-arrow"  to place more than one machine instruction per
line and  the use  of  seven alternate  PDP-10 mnemonics.

	The seven alternate PDP-10 mnemonics are LAC, DAC, CAR, CDR,
DIP,   DAP and GO for  MOVE, MOVEM, HLRZ,  HRRZ,  HRLM, HRRM and JRST
respectively. The LAC,  DAC, DIP, DAP  come from PDP-1  nomensclature
and are shorter  and more pronoucible than  their PDP-10 equivalents.
The  CAR and CDR are from LISP which  got them from the IBM-709.  The
GO comes from  ALGOL and is shorter  and more descriptive than  JRST.
The  PDP-10 op  code names  sacrifice  pronoucibility  for systematic
nomensclature; and although I once proposed having alternate  concise
euphonious names  for the most  frequently used operations;  the idea
was  quite unpopular and so  I have abandoned it for  all except the 
above seven mnemonics.